package com.h2.ref.server.proxy;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HttpProxyServlet extends HttpServlet {

   /** serialVersionUID */
   private static final long serialVersionUID = 1L;
   
   ////
   
   private String _host;
   
   private String _proxyHost;
   
   private String _proxyPort;
   
   private Boolean _rewriteHost;
   
   private String _baseUrl;
   
   private String _encoding;
   
   private Boolean _keepHeaders = Boolean.TRUE;
   
   private String _uri;
   
   private ProxyProvider _proxyProvider = new ProxyProvider();
   
   ////
   ////
   
   /* (non-Javadoc)
    * @see javax.servlet.GenericServlet#init()
    */
   public void init() throws ServletException {
      setHost(getInitParameter("host"));
      if (getHost() == null) {
         System.out.println("HttpProxyServlet needs a host in the parameter.");
         throw new ServletException(
               "HttpProxyServlet needs a host in the parameter.");
      }
      
      //proxyHost & proxyPort
      setProxyHost(getInitParameter("proxyHost"));
      setProxyPort(getInitParameter("proxyPort"));
      
      //rewriteHost
      setRewriteHost(Boolean.parseBoolean(getInitParameter("rewriteHost")));
      
      //encoding
//      encoding = getInitParameter("encoding");
      
      //uri
      setUri(ProxyUtils.normalizeUri(getInitParameter("uri")));
      
      //keepHeaders
      if(getInitParameter("keepHeaders") != null) {
         setKeepHeaders(Boolean.parseBoolean(
               getInitParameter("headers")));
      }
      
      //baseUrl
      setBaseUrl(getInitParameter("baseUrl"));
      if(getBaseUrl() == null) {
         setBaseUrl("");
      }
      
//      disableAcceptEncoding = getInitParameter("gzip");
//      
//      if (keepHeaders == null)
//         keepHeaders = "true";
//      if (disableAcceptEncoding == null)
//         disableAcceptEncoding = "false";
   }
   
   /* (non-Javadoc)
    * @see javax.servlet.http.HttpServlet#doGet(
    *    javax.servlet.http.HttpServletRequest,
    *    javax.servlet.http.HttpServletResponse)
    */
   public void doGet(HttpServletRequest httpservletrequest,
         HttpServletResponse httpservletresponse) throws ServletException,
            IOException {
      doAction(httpservletrequest, httpservletresponse);
   }
   
   /* (non-Javadoc)
    * @see javax.servlet.http.HttpServlet#doPost(
    *    javax.servlet.http.HttpServletRequest,
    *    javax.servlet.http.HttpServletResponse)
    */
   public void doPost(HttpServletRequest request,
         HttpServletResponse response) throws ServletException,
         IOException {
      throw new UnsupportedOperationException("Not implemented yet");
   }
   
   public void doAction(HttpServletRequest request,
         HttpServletResponse response) throws ServletException,
         IOException {
      
      String queryStr = request.getQueryString();
      String proxyPath = getHost();
      
      /*
       * If this value is not empty, then proxy will use the request's URI
       * exclude the provided value in the final request. Default value is empty
       * (do not rewrite URI).
       */
      if (getUri() != null) {
         String requestUri = request.getRequestURI();
         if (requestUri != null) {
            if (!requestUri.startsWith(getUri())) {
               requestUri = null;
            }
            else if (getUri().length() >= requestUri.length()) {
               requestUri = null;
            }
            else {
               requestUri = requestUri.substring(getUri().length());
            }
               
            if (requestUri != null) {
               proxyPath = ProxyUtils.combineUri(proxyPath, requestUri);
            }
         }
      }
      
      proxyPath = ProxyUtils.addQuery(
            proxyPath + getBaseUrl() + request.getServletPath()
            + request.getPathInfo(), queryStr);
      
      getProxyer().proxy(request.getMethod(), //method
            getHost(), //host
            proxyPath, //proxyPath
            null, // table?
            null, //defaultTimeout
            getProxyHost(), //proxyHost
            getProxyPort(), //proxyPort
            null, //encoding
            getKeepHeaders(), //keepHeaders
            getRewriteHost(), //rewriteHost
            request, response);
   }
   
   
   
   ////
   ////

   /**
    * @return the host
    */
   public String getHost() {
      return _host;
   }

   /**
    * @param host the host to set
    */
   public void setHost(String host) {
      _host = host;
   }

   /**
    * @return the proxyHost
    */
   public String getProxyHost() {
      return _proxyHost;
   }

   /**
    * @param proxyHost the proxyHost to set
    */
   public void setProxyHost(String proxyHost) {
      _proxyHost = proxyHost;
   }

   /**
    * @return the proxyPort
    */
   public String getProxyPort() {
      return _proxyPort;
   }

   /**
    * @param proxyPort the proxyPort to set
    */
   public void setProxyPort(String proxyPort) {
      _proxyPort = proxyPort;
   }

   /**
    * @return the rewriteHost
    */
   public Boolean getRewriteHost() {
      return _rewriteHost;
   }

   /**
    * @param rewriteHost the rewriteHost to set
    */
   public void setRewriteHost(Boolean rewriteHost) {
      _rewriteHost = rewriteHost;
   }

   /**
    * @return the baseUrl
    */
   public String getBaseUrl() {
      return _baseUrl;
   }

   /**
    * @param baseUrl the baseUrl to set
    */
   public void setBaseUrl(String baseUrl) {
      _baseUrl = baseUrl;
   }

   /**
    * @return the encoding
    */
   public String getEncoding() {
      return _encoding;
   }

   /**
    * @param encoding the encoding to set
    */
   public void setEncoding(String encoding) {
      _encoding = encoding;
   }

   /**
    * @return the keepHeaders
    */
   public Boolean getKeepHeaders() {
      return _keepHeaders;
   }

   /**
    * @param keepHeaders the keepHeaders to set
    */
   public void setKeepHeaders(Boolean keepHeaders) {
      _keepHeaders = keepHeaders;
   }

   /**
    * @return the uri
    */
   public String getUri() {
      return _uri;
   }

   /**
    * @param uri the uri to set
    */
   public void setUri(String uri) {
      _uri = uri;
   }

   /**
    * @return the proxyer
    */
   public ProxyProvider getProxyer() {
      return _proxyProvider;
   }

   /**
    * @param proxyer the proxyer to set
    */
   public void setProxyer(ProxyProvider proxyer) {
      _proxyProvider = proxyer;
   }

}
